;;; init-generic.el --- Generic settings -*- lexical-binding: t -*-
;;; Commentary:

;;; Code:

(use-package gcmh
  :ensure t
  :hook (elpaca-after-init . gcmh-mode)
  :custom
  (gcmh-idle-delay 'auto))

;; 整理 `~/.emacs.d/' 下零散的文件
(use-package no-littering
  :demand t
  :ensure t
  :config
  ;; for lsp-bridge
  (let ((multiserver-dir (expand-file-name "multiserver" no-littering-var-directory))
        (langserver-dir (expand-file-name "langserver" no-littering-var-directory)))
    (unless (file-exists-p multiserver-dir)
      (make-directory multiserver-dir t))
    (unless (file-exists-p langserver-dir)
      (make-directory langserver-dir t)))

  ;; for backup
  (with-eval-after-load 'files
    (setq auto-save-file-name-transforms
          `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))
    (setq backup-directory-alist
          `(("\\`/tmp/" . nil)
            ("\\`/dev/shm/" . nil)
            ("." . ,(no-littering-expand-var-file-name "backup/")))))

  ;; for undo-tree
  (with-eval-after-load 'undo-tree
    (setq undo-tree-history-directory-alist
          `(("\\`/tmp/" . nil)
            ("\\`/dev/shm/" . nil)
            ("." . ,(no-littering-expand-var-file-name "undo-tree-hist/")))))

  ;; for tempel
  (with-eval-after-load 'tempel
    (setq tempel-path (expand-file-name "templates.el" no-littering-etc-directory)))

  ;; for dape
  (with-eval-after-load 'dape
    (setq dape-adapter-dir (concat no-littering-var-directory "debug-adapters")
          dape-default-breakpoints-file (concat no-littering-var-directory "dape-breakpoints")))

  ;; for blink-search
  (with-eval-after-load 'blink-search
    (setq blink-search-db-path (expand-file-name "blink-search.db" no-littering-var-directory)
          blink-search-history-path (expand-file-name
                                     (concat no-littering-var-directory
                                             (file-name-as-directory "blink-search")
                                             "history.txt")))))

;; emacs 通用设置
(use-package emacs
  :ensure nil
  :hook (((org-mode markdown-mode) . (lambda ()
                                       (setq-local truncate-lines nil  ; 允许折行
                                                   line-move-visual t) ; 上下移动按视觉行
                                       (show-paren-mode -1)            ; 不标识配对的括号
                                       (visual-line-mode 1)))
         (prog-mode . (lambda ()
                        (hs-minor-mode 1)                      ; 文本扩展
                        (show-paren-local-mode 1)              ; 括号提示
                        (display-fill-column-indicator-mode 1) ; 显示换行参考线
                        (display-line-numbers-mode 1)))        ; 显示行号
         (elpaca-after-init . (lambda ()
                                (auto-save-visited-mode 1)  ; 自动保存文件
                                (column-number-mode 1)      ; 统计列号
                                (delete-selection-mode 1)   ; 选中文本后输入文本会替换文本
                                (global-auto-revert-mode 1) ; 当另一程序修改了文件时，让 Emacs 及时刷新 Buffer
                                (global-hl-line-mode 1)     ; 高亮当前行
                                (global-so-long-mode)       ; 避免长行卡死
                                (global-subword-mode 1)     ; word 移动支持 FooBar 的格式
                                (line-number-mode 1)        ; 统计行号
                                (repeat-mode 1)             ; 简化重复执行命令的操作
                                (save-place-mode 1))))      ; 保存光标位置
  :init
  ;; Add prompt indicator to `completing-read-multiple'.
  ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
  (defun crm-indicator (args)
    (cons (format "[CRM%s] %s"
                  (replace-regexp-in-string
                   "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
                   crm-separator)
                  (car args))
          (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

  ;; Do not allow the cursor in the minibuffer prompt
  (setq minibuffer-prompt-properties
        '(read-only t cursor-intangible t face minibuffer-prompt))
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

  ;; Support opening new minibuffers from inside existing minibuffers.
  (setq enable-recursive-minibuffers t)

  ;; Emacs 28 and newer: Hide commands in M-x which do not work in the current
  ;; mode.  Vertico commands are hidden in normal buffers. This setting is
  ;; useful beyond Vertico.
  (setq read-extended-command-predicate #'command-completion-default-include-p)
  :custom
  (calendar-longitude 87)
  (calendar-latitude 43)
  (calendar-chinese-celestial-stem ["甲" "乙" "丙" "丁" "戊" "己" "庚" "辛" "壬" "癸"])
  (calendar-chinese-terrestrial-branch ["子" "丑" "寅" "卯" "辰" "巳" "午" "未" "申" "酉" "戌" "亥"])
  (visual-line-fringe-indicators '(nil right-curly-arrow)) ; 显示这行符号
  :config
  (setq completion-auto-select nil              ; 避免默认自动选择
        confirm-kill-processes nil              ; 退出自动杀掉进程
        display-raw-bytes-as-hex t              ; 以 16 进制显示字节数
        global-auto-revert-non-file-buffers nil ; 避免在非文件缓冲区刷新 buffer
        inhibit-compacting-font-caches t        ; 使用字体缓存，避免卡顿
        large-file-warning-threshold nil        ; 打开大文件不提示
        mouse-yank-at-point t                   ; 粘贴到光标处而不是鼠标指针处
        use-dialog-box nil                      ; never pop dialog
        use-short-answers t                     ; y-or-n 替换 yes-or-no
        xref-search-program 'ripgrep)           ; xref 使用 ripgrep 搜索

  (setq-default comment-style 'indent                ; 注释风格
	        cursor-in-non-selected-windows nil   ; 隐藏非活动窗口的光标
                cursor-type '(bar . 6)               ; 光标样式
                display-line-numbers-type t          ; 显示绝对行号
                display-line-numbers-width 4         ; 行号宽度
                fill-column 120                      ; 折行参考线在第 120 个字符处提示
                initial-major-mode 'fundamental-mode ; 默认主要模式
	        indent-tabs-mode nil                 ; 缩进不使用制表符
                line-spacing 0                       ; 设置行高
                ring-bell-function 'ignore           ; 禁止响铃
                truncate-lines t                     ; 默认截断（不折行）
                visible-bell nil                     ; 关闭警告音与窗口闪烁
                word-wrap t                          ; 若折行，则避免在单词上折行
                word-wrap-by-category t              ; 若折行，则避免在空格处折行
                warning-minimum-level :error)        ; 屏蔽 warning

  ;; 大文件支持
  ;; From: emacs-china.org/t/topic/25811/9?u=harl
  (setq-default bidi-display-reordering nil ; 计算 bidi (为了从右往左书写的文本如阿拉伯文和其他文本混合能正常显示)
                bidi-paragraph-direction 'left-to-right) ; 设置缓冲区的文字方向为从左到右
  (setq bidi-inhibit-bpa t
        long-line-threshold 1000
        large-hscroll-threshold 1000
        syntax-wholeline-max 1000)

  ;; 鼠标滚动设置
  (setq mouse-wheel-scroll-amount-horizontal 9    ; 水平滚动步长
        scroll-step 1                             ; 垂直滚动步长
        scroll-margin 1                           ; 滚动边距
        scroll-conservatively 100                 ; 控制滚动行为，避免光标自动居中但允许有限度的滚动
        make-cursor-line-fully-visible nil        ; 不强制光标行完全可见
        auto-window-vscroll nil)                  ; 禁用垂直滚动补偿

  ;; emacs 默认禁用一些外行不理解的命令，在执行这些命令时会弹出交互信息以避免意外执行
  ;; 以下将启用一些命令
  (put 'narrow-to-region 'disabled nil)
  (put 'dired-find-alternate-file 'disabled nil))

(provide 'init-generic)
;;; init-generic.el ends here
